/*
 * @Date: 2023-12-18 17:56:34
 * @LastEditors: 玄绮 shijiahansi@qq.com
 * @LastEditTime: 2024-04-19 18:22:54
 * @FilePath: \server\src\server\app\Application.h
 */
#ifndef CHATSERVER_H
#define CHATSERVER_H

#include "ChatRoomManager.h"
#include "ChatSessionManager.h"
#include "config/Config.h"

#include <boost/asio.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/ssl/context.hpp>
#include <boost/mysql.hpp>
#include <boost/system/system_error.hpp>
#include <http/ChatHttpServer.h>

using boost::asio::ip::tcp;
namespace net = boost::asio;           // from <boost/asio.hpp>
using tcp     = boost::asio::ip::tcp;  // from <boost/asio/ip/tcp.hpp>

class ChatServer {
private:
    static ChatServer* app;

protected:
    net::io_context ioc;
    tcp::acceptor acceptor;
    struct Config config;

    // The SSL context, required to establish TLS connections.
    // The default SSL options are good enough for us at this point.
    boost::asio::ssl::context ssl_ctx;

    // Represents a connection to the MySQL server.
    boost::mysql::tcp_ssl_connection mysqlconn;
    ChatHttpServer::SharedPtr http_server;

    ChatSessionManager::SharedPtr m_sessionManager;
    ChatRoomManager::SharedPtr m_roomManager;

    ChatServer(const tcp::endpoint& endpiont);

public:
    ~ChatServer();

    static ChatServer& getInstance();
    static net::io_context& io_context();

protected:
    bool initConfig();
    void initMysql();
    void initConnect();
    void initHttpServer();

public:
    void exec();
    boost::mysql::tcp_ssl_connection& mysqlConnection();
    ChatSessionManager& sessionManager();
    ChatRoomManager& roomManager();

protected:
    void doAccept();

    void newSessionHandler(tcp::socket& socket);
};

#endif